class Deps {
  constructor() {
    this.subscribers = new Set();
  }
  // 收集依赖
  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  }
  // 触发依赖
  notify() {
    this.subscribers.forEach((effect) => {
      effect();
    });
  }
}

let activeEffect = null;

function watchEffect(fn) {
  activeEffect = fn;
  fn();
  activeEffect = null;
}

let targetMap = new WeakMap();

function getDep(target, key) {
  let depMap = targetMap.get(target);
  if (!depMap) {
    depMap = new Map();
    targetMap.set(target, depMap);
  }
  let dep = depMap.get(key);
  if (!dep) {
    dep = new Deps();
    depMap.set(key, dep);
  }
  return dep;
}

// 自动收集依赖，vue2.x版本
// function relative(raw){
//   Object.keys(raw).forEach(key =>{
//     let dep = getDep(raw,key);
//     let value = raw[key]
//     Object.defineProperty(raw,key,{
//       get(){
//         dep.depend()
//         return value
//       },
//       set(newValue){
//         if ( value !== newValue) {
//           value = newValue
//           dep.notify();
//         }
//       }
//     })
//   })
//   return raw
// }
// 自动收集依赖，vue3.x版本
function relative(raw) {
  return new Proxy(raw, {
    set(target, key, newValue) {
      if (target[key] !== newValue) {
        const dep = getDep(target, key);
        target[key] = newValue;
        dep.notify();
      }
    },
    get(target, key) {
      const dep = getDep(target, key);
      dep.depend();
      return target[key];
    },
  });
}

// let obj = relative({ a: 1, b: 2 });

// watchEffect(function () {
//   console.log("watchEffect1: ", obj.a, obj.b);
// });

// watchEffect(function () {
//   console.log("watchEffect2: ", obj.b);
// });

// obj.a = obj.a + 1;
// obj.b = obj.b + 1;
